package com.jinzhi.jzsynthesize.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.type.EnumErrorCode;
import com.jinzhi.common.utils.EhCacheUtil;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.ValidUtils;
import com.jinzhi.jzsynthesize.ExcelVo.ResultEnterVo;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.pojo.ErroeDownVo;
import com.jinzhi.jzweb.pojo.ErrorCodeVo;
import com.jinzhi.jzweb.service.*;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.RoleService;
import com.jinzhi.sys.service.UserRoleService;
import com.jinzhi.sys.service.UserService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;

@Controller
@AllArgsConstructor
@RequestMapping("/synthesize/resultEnter")
public class ResultEnterController extends BaseController {

	@Autowired
	private ExaminationResultsService examinationResultsService;
	@Autowired
	private UserService userService;
	@Autowired
	private ExaminationBatchService examinationBatchService;
	@Autowired
	private OrganizationNewsService organizationNewsService;
	@Autowired
	private OrganizationRolesService organizationRolesService;
	@Autowired
	private UserRoleService userRoleService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private StuSignUpService stuSignUpService;
	@Autowired
	private ExpertsService expertsService;

	@GetMapping()
	@RequiresPermissions("synthesizeWeb:resultEnter:resultEnter")
	String resultEnter (){
		return "synthesizeWeb/resultEnter/resultEnter";
	}

	@Log("成绩录入")
	@ResponseBody
	@GetMapping("/list")
	@RequiresPermissions("synthesizeWeb:resultEnter:resultEnter")
	public Result<Page<ExaminationResultsDO>> list(HttpServletRequest req ,ExaminationResultsDO examinationBatchDO , int pageSize , int pageNumber){
		//查询用户角色
		String roleName = getRoleNames();
		if (!roleName.contains("超级用户角色")) {
			Map map = new HashMap();

			Object orgId = req.getSession().getAttribute("orgId");
			if (orgId != null){
				map.put("orgId",orgId);
			}else {
				map.put("orgId",this.getUser().getOrgId());
			}

			map.put("ebatchId",examinationBatchDO.getEbatchId());


			Page<ExaminationResultsDO> page = examinationResultsService.findList(map, pageNumber , pageSize);

			List<ExaminationResultsDO> list = page.getRecords();
			for (ExaminationResultsDO exam :list){
				ExaminationBatchDO ebatch = examinationBatchService.selectById(exam.getEbatchId());
				if (ebatch != null){
					exam.setEbatchName(ebatch.getName());
					exam.setDate(ebatch.getStartTime());
				}

				StuSignUpDO stu = stuSignUpService.selectById(exam.getStuSignId());
				if (stu != null){
					exam.setStuName(stu.getName());
				}

				UserDO user = userService.selectById(exam.getEnterExpertId());
				if (user != null){
					if (user.getName() != null){
						exam.setExpertName(user.getName());
					}else {
						exam.setExpertName(user.getUsername());
					}
				}
			}
			page.setRecords(list);

			return Result.ok(page);
		}else {
			Map map = new HashMap();
			map.put("ebatchId",examinationBatchDO.getEbatchId());
			Page<ExaminationResultsDO> page = examinationResultsService.findLists(map,pageNumber , pageSize);
			return Result.ok(page);
		}
	}

	@Log("查询考试批次列表-无分页")
	@ResponseBody
	@GetMapping("/eBatch")
	Result<?> findEBatchList(){
		Wrapper<ExaminationBatchDO> wrapper = new EntityWrapper<>();
		wrapper.eq("state" , 5);
//		wrapper.eq("type" , 1);

		List<ExaminationBatchDO> eBatchList = examinationBatchService.selectList(wrapper);

		return Result.ok(eBatchList);
	}

	/**
	 * 导出考生信息
	 *
	 * @param response
	 */
	@Log("导出考生信息")
	@RequestMapping("/download")
	@RequiresPermissions("synthesizeWeb:resultEnter:import")
	@ResponseBody
	public void downloadImportTemplate(HttpServletResponse response ,HttpServletRequest req, Long ebatchId) {
		List<ResultEnterVo> list = new LinkedList<>();

		//查询考试批次
		ExaminationBatchDO ebatch = examinationBatchService.selectById(ebatchId);

		List<StuSignUpDO> stuList = null;

		//查询用户角色
		String roleName = getRoleNames();
		if (!roleName.contains("超级用户角色")) {
			Object orgId = req.getSession().getAttribute("orgId");
			if (orgId != null){
				stuList = stuSignUpService.findByKv("cbatch_id" , ebatch.getCbatchId() , "org_id" , orgId);
			}else {
				//查询报名的考考生信息
				stuList = stuSignUpService.findByKv("cbatch_id" , ebatch.getCbatchId() , "org_id" , this.getUser().getOrgId());
			}

		}else {
			stuList = stuSignUpService.findByKv("cbatch_id" , ebatch.getCbatchId());
		}

		for (StuSignUpDO stu : stuList){
			UserDO user = userService.selectById(stu.getUserId());
			list.add(new ResultEnterVo(stu , user));
		}

		//导出操作
		EasyPoiUtil.exportExcel(list, "综合管理平台-考生信息导出", "考生信息导出", ResultEnterVo.class, "综合管理平台-考生信息导出", response);
	}


	/**
	 * 考生信息导入
	 *
	 * @param file excel文件
	 */
	@Log("技能成绩导入")
	@PostMapping("/import")
	@ResponseBody
	@Transactional
	@RequiresPermissions("synthesizeWeb:resultEnter:import")
	public Result<?> importExcel(HttpServletRequest req,@RequestParam("file") MultipartFile file, String eBatchId) {
		//---------------------------------检测导入信息及条件-----------------------------------------
		//第一步--判断文件格式
		if (!"application/vnd.ms-excel".equals(file.getContentType())) {
			return Result.fail("文件格式错误，请选择.xls文件");
		}

		//第二步--解析文件获得数据
		List<ResultEnterVo> list = EasyPoiUtil.importExcel(file, 1, 2, ResultEnterVo.class);
		if (list.size() == 0) {
			return Result.fail("Excel数据为空，请完善");
		}

		//第三步--判断导入人员身份，获取导入人员信息
		//todo 超级管理员是否需要判断导入信息
		if (this.getUser().getOrgId() != null) {
			OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(this.getUser().getOrgId());
			if (organizationNewsDO == null) {
				return Result.fail("您的所属机构信息错误，无法导入信息！");
			} else {

				Object orgId = req.getSession().getAttribute("orgId");
				if (orgId != null){
					OrganizationRolesDO organizationRolesDOs = organizationRolesService.findOneByKv("org_id", orgId, "role_type", 5);
					if (organizationRolesDOs == null) {
						return Result.fail("您的所属机构不具备考核站点角色，无法导入信息！");
					}
				}else {
					OrganizationRolesDO organizationRolesDOs = organizationRolesService.findOneByKv("org_id", this.getUser().getOrgId(), "role_type", 5);
					if (organizationRolesDOs == null) {
						return Result.fail("您的所属机构不具备考核站点角色，无法导入信息！");
					}
				}
			}
		}
		int startRow = 3;
		int cout = 1;//错误信息计数
		List<ExaminationResultsDO> upDOList = new ArrayList<>();
		List<ErrorCodeVo> list1 = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			StringBuilder sb = new StringBuilder();
			//第一步验证是否存在空值
			if (StringUtils.isBlank(list.get(i).getName())) {
				sb.append("第" + (i + startRow) + "行姓名未填写，请完善！" + ";");
			} else {
				if (StringUtils.isBlank(list.get(i).getMobile())) {
					sb.append("第" + (i + startRow) + "行手机号码未填写，请完善！" + ";");
				} else {
					if (StringUtils.isBlank(list.get(i).getIdNumber())) {
						sb.append("第" + (i + startRow) + "行身份证号码未填写，请完善！" + ";");
					} else {

						if (StringUtils.isBlank(list.get(i).getResult())) {
							sb.append("第" + (i + startRow) + "行成绩未填写，请完善" + ";");
						} else {
							//第二步验证电话号码
							if (!ValidUtils.isMobile(list.get(i).getMobile())) {
								sb.append("第" + (i + startRow) + "行手机号码格式错误，请完善！" + ";");
							} else {
								//第三步验证身份证号码
								if (!ValidUtils.isIDCard(list.get(i).getIdNumber())) {
									sb.append("第" + (i + startRow) + "行身份证号码格式错误，请完善！" + ";");
								} else {
									if(sb.length() == 0){
										//第四步排重验证（自身比较）
										for (int j = 0; j < list.size(); j++) {
											if (i != j) {
												if (list.get(i).getName().equals(list.get(j).getName())) {
													sb.append("第" + (i + startRow) + "行跟第" + (j + startRow) + "行姓名重复，重复值：" + list.get(i).getName() + ";");
												}
												if (list.get(i).getMobile().equals(list.get(j).getMobile())) {
													sb.append("第" + (i + startRow) + "行跟第" + (j + startRow) + "行手机号重复，重复值：" + list.get(i).getMobile() + ";");
												}
												if (list.get(i).getIdNumber().equals(list.get(j).getIdNumber())) {
													sb.append("第" + (i + startRow) + "行跟第" + (j + startRow) + "行身份证号码重复，重复值：" + list.get(i).getIdNumber() + ";");
												}
											}
										}

										//根据手机号码获取用户信息并判断
										UserDO userDO = userService.findOneByKv("mobile", list.get(i).getMobile());

										if (userDO == null){
											sb.append("第" + (i + startRow) + "行该考生用户信息不存在，请修改后重新上传！" + ";");
										}else {
											//查询认证批次
											ExaminationBatchDO eBatch = examinationBatchService.selectById(eBatchId);

											StuSignUpDO stu = stuSignUpService.findOneByKv("user_id" , userDO.getId() , "cbatch_id", eBatch.getCbatchId(), "org_id" , this.getUser().getOrgId());

											if (stu == null){
												sb.append("第" + (i + startRow) + "行该考生报名信息不存在，请修改后重新上传！" + ";");
											}else {
												ExaminationResultsDO resultsDO = examinationResultsService.findOneByKv("ebatch_id" , eBatchId , "stu_sign_id", stu.getId());

												//查询考试批次
												if (resultsDO != null) {
													sb.append("第" + (i + startRow) + "行考生已存在该成绩数据！" + ";");
												} else {

													ExaminationResultsDO result = new ExaminationResultsDO();
													result.setEbatchId(Long.parseLong(eBatchId));
													result.setCbatchId(eBatch.getCbatchId());
													result.setStuSignId(stu.getId());
													result.setState(0);
													result.setEnterExpertId(this.getUserId());
													result.setTotalScore(Double.parseDouble(list.get(i).getResult()));
													upDOList.add(result);
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}

			if (sb.length() > 0) {
				ErrorCodeVo errorCodeVo = new ErrorCodeVo();
				errorCodeVo.setSeq(cout);
				cout += 1;
				errorCodeVo.setErrorCode(sb.toString());
				list1.add(errorCodeVo);
			}
		}

		if (list1.size() == 0) {
			boolean c = examinationResultsService.insertBatch(upDOList, upDOList.size());
			if (c) {
				return Result.ok("成功导入" + list.size() + "条数据");
			} else {
				return Result.fail("成绩信息添加错误，请稍后重试或联系管理员");
			}
		} else {

			JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list1));
			//将list1存到缓存中
			EhCacheUtil.put("result" + this.getUserId(), jsonArray);
			return Result.build(EnumErrorCode.FileImportError.getCode(), EnumErrorCode.FileImportError.getMsg());
		}
	}


	/**
	 * 导出错误信息
	 *
	 * @param request
	 * @param response
	 * @throws Exception
	 * @author wh
	 */
	@Log("导出错误信息")
	@GetMapping("/importError")
	@ResponseBody
	@Transactional
	@RequiresPermissions("synthesizeWeb:resultEnter:import")
	public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 告诉浏览器用什么软件可以打开此文件
		response.setHeader("content-Type", "application/vnd.ms-excel");
		// 下载文件的默认名称
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("技能成绩导入错误信息", "UTF-8") + ".xls");
		//编码
		response.setCharacterEncoding("UTF-8");
		String jsonArray = EhCacheUtil.get("result" + this.getUserId()).toString();
		JSONArray arrayList = JSONArray.parseArray(jsonArray);
		//转换为目标对象list
		List<ErroeDownVo> groupList = JSONObject.parseArray(arrayList.toJSONString(), ErroeDownVo.class);
		Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ErroeDownVo.class, groupList);
		workbook.write(response.getOutputStream());
	}
}
